package main

import (
	"encoding/json"
	"fmt"
	"gozero-chat-example/config"
	database "gozero-chat-example/database/db"
	"gozero-chat-example/model"
	"gozero-chat-example/routes"
	"log"
	"net/http"
	"net/url"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"syscall"
	"time"

	"github.com/go-chi/chi"
	"github.com/zeromicro/go-zero/core/logx"
	"github.com/zeromicro/go-zero/core/service"
	"github.com/zeromicro/go-zero/rest"
)

// 确保日志格式正确
func init() {
	logx.DisableStat()

	cfg, err := config.LoadConfig()
	if err != nil {
		log.Fatalf("加载配置文件失败: %v", err)
	}

	// 初始化数据库连接
	err = database.InitDB(cfg)
	if err != nil {
		log.Fatalf("初始化数据库连接失败: %v", err)
	}
}

func main() {

	// 创建一个多服务管理器
	group := service.NewServiceGroup()
	defer group.Stop()

	// 添加WebSocket服务
	wsServer := NewWebSocketServer(database.DB)
	group.Add(wsServer)

	// 添加REST API服务
	apiServer := createApiServer(wsServer)
	group.Add(apiServer)

	// 启动服务
	fmt.Println("服务器启动中，监听端口: 4456")
	group.Start()

	// 等待中断信号
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit
	fmt.Println("正在关闭服务器...")
	fmt.Println("REST API服务器关闭")
}

// 创建API服务器 包含静态文件服务
func createApiServer(wsServer *WebSocketServer) *rest.Server {
	// 创建默认的REST服务器配置
	conf := rest.RestConf{
		Host: "0.0.0.0",
		Port: 4456,
	}

	// 创建REST服务器
	server := rest.MustNewServer(conf)

	// 注册静态文件
	routes.ServerRegis(server)
	fmt.Println("静态文件注册成功")

	// 登录
	server.AddRoute(rest.Route{
		Method:  http.MethodPost,
		Path:    "/api/login",
		Handler: handleLogin,
	})

	// 获取房间列表
	server.AddRoute(rest.Route{
		Method:  http.MethodGet,
		Path:    "/api/rooms",
		Handler: func(w http.ResponseWriter, r *http.Request) { handleGetRooms(w, r, wsServer) },
	})

	//// 在获取房间列表路由下方添加搜索路由
	//server.AddRoute(rest.Route{
	//    Method:  http.MethodGet,
	//    Path:    "/api/rooms/search",
	//    Handler: func(w http.ResponseWriter, r *http.Request) { handleSearchRooms(w, r) },
	//})

	// 创建房间
	server.AddRoute(rest.Route{
		Method:  http.MethodPost,
		Path:    "/api/rooms",
		Handler: func(w http.ResponseWriter, r *http.Request) { handleCreateRoom(w, r, wsServer) },
	})

	// WebSocket
	server.AddRoute(rest.Route{
		Method:  http.MethodGet,
		Path:    "/ws",
		Handler: func(w http.ResponseWriter, r *http.Request) { handleWebSocket(w, r, wsServer) },
	})

	// 获取房间在线用户列表
	server.AddRoute(rest.Route{
		Method:  http.MethodGet,
		Path:    "/api/rooms/users",
		Handler: func(w http.ResponseWriter, r *http.Request) { handleGetRoomUsers(w, r, wsServer) },
	})

	// 获取房间消息历史
	server.AddRoute(rest.Route{
		Method:  http.MethodGet,
		Path:    "/api/rooms/{room_id}/messages",
		Handler: func(w http.ResponseWriter, r *http.Request) { handleGetRoomMessages(w, r, wsServer) },
	})

	// 上报消息已读
	server.AddRoute(rest.Route{
		Method:  http.MethodPost,
		Path:    "/api/rooms/{room_id}/messages/{msg_id}/read",
		Handler: func(w http.ResponseWriter, r *http.Request) { handleReadMessage(w, r, wsServer) },
	})

	// 新增房间删除接口
	server.AddRoute(rest.Route{
		Method:  http.MethodDelete,
		Path:    "/api/rooms/{room_id}",
		Handler: func(w http.ResponseWriter, r *http.Request) { handleDeleteRoom(w, r, wsServer) },
	})

	// 注册好友相关API
	server.AddRoute(rest.Route{
		Method:  http.MethodGet,
		Path:    "/api/friends",
		Handler: handleGetFriends,
	})
	server.AddRoute(rest.Route{
		Method:  http.MethodPost,
		Path:    "/api/friends",
		Handler: handleAddFriend,
	})
	server.AddRoute(rest.Route{
		Method:  http.MethodDelete,
		Path:    "/api/friends",
		Handler: handleDeleteFriend,
	})

	// 用户信息接口
	server.AddRoute(rest.Route{
		Method:  http.MethodGet,
		Path:    "/api/userinfo",
		Handler: handleGetUserInfo,
	})

	// 修改/api/online-users接口，统计所有房间内活跃WebSocket用户（去重）
	server.AddRoute(rest.Route{
		Method: http.MethodGet,
		Path:   "/api/online-users",
		Handler: func(w http.ResponseWriter, r *http.Request) {
			userSet := make(map[string]struct{})
			for _, room := range wsServer.Rooms {
				for uid := range room.Clients {
					userSet[uid] = struct{}{}
				}
			}
			count := len(userSet)
			w.Header().Set("Content-Type", "application/json")
			json.NewEncoder(w).Encode(map[string]int{"count": count})
		},
	})

	// 新增：查询所有匹配中房间
	server.AddRoute(rest.Route{
		Method:  http.MethodGet,
		Path:    "/api/matching-rooms",
		Handler: handleGetMatchingRooms,
	})

	// 新增：通过name+creator_id查房间数字ID的接口
	server.AddRoute(rest.Route{
		Method:  http.MethodGet,
		Path:    "/api/room-id-by-name",
		Handler: handleGetRoomIdByNameAndCreator,
	})

	// 新增：获取房间用户准备状态API
	server.AddRoute(rest.Route{
		Method:  http.MethodGet,
		Path:    "/api/rooms/ready-status",
		Handler: handleGetRoomReadyStatus,
	})

	// 新增：更新用户准备状态API
	server.AddRoute(rest.Route{
		Method:  http.MethodPost,
		Path:    "/api/user/ready-status",
		Handler: handleUpdateUserReadyStatus,
	})

	// 设置房间为匹配中
	server.AddRoute(rest.Route{
		Method:  http.MethodPost,
		Path:    "/api/rooms/{room_id}/matching",
		Handler: handleSetRoomMatching,
	})

	// 取消匹配
	server.AddRoute(rest.Route{
		Method:  http.MethodPost,
		Path:    "/api/rooms/{room_id}/cancel-matching",
		Handler: handleCancelRoomMatching,
	})

	server.Use(func(next http.HandlerFunc) http.HandlerFunc {
		return func(w http.ResponseWriter, r *http.Request) {
			w.Header().Set("Access-Control-Allow-Origin", "*")
			w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
			w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
			if r.Method == "OPTIONS" {
				w.WriteHeader(http.StatusOK)
				return
			}
			next(w, r)
		}
	})

	return server
}

// 生成简单的令牌
func generateToken(username string) string {
	// 实际项目中应该使用JWT等更安全的方法
	return fmt.Sprintf("%s-%d", username, time.Now().UnixNano())
}

// 用户登录请求
type LoginRequest struct {
	Username string `json:"username"`
}

// 用户登录响应
type LoginResponse struct {
	Token  string `json:"token"`
	UserID string `json:"user_id"`
}

// 创建房间请求
type CreateRoomRequest struct {
	Name     string `json:"name"`
	MaxUsers int    `json:"max_users"`
}

// 创建房间响应
type CreateRoomResponse struct {
	RoomID   string `json:"room_id"`
	RoomName string `json:"room_name"`
}

// 获取房间列表
func handleGetRooms(w http.ResponseWriter, r *http.Request, wsServer *WebSocketServer) {
	dbRooms, err := model.GetAllRooms(database.DB)
	if err != nil {
		writeJSONError(w, "数据库查询失败", http.StatusInternalServerError)
		return
	}

	// 统计每个房间的在线人数
	userCounts := map[string]int{}
	wsServer.mu.RLock()
	for id, room := range wsServer.Rooms {
		userCounts[id] = len(room.Clients)
	}
	wsServer.mu.RUnlock()

	var roomInfos []map[string]interface{}
	now := time.Now()

	for _, room := range dbRooms {
		// idStr应为数据库主键uint转字符串
		idStr := fmt.Sprintf("%d", room.ID)
		userCount := userCounts[idStr]

		// 检查是否需要删除房间
		if room.EmptySince != nil && now.Sub(*room.EmptySince) > 30*time.Second {
			// 从数据库中删除房间
			if err := model.DeleteRoomByID(database.DB, idStr); err != nil {
				logx.Errorf("Failed to delete empty room %s from database: %v", idStr, err)
			} else {
				logx.Infof("Deleted empty room %s from database", idStr)
			}
			// 从内存中删除房间
			wsServer.mu.Lock()
			if wsRoom := wsServer.Rooms[idStr]; wsRoom != nil {
				delete(wsServer.Rooms, idStr)
			}
			wsServer.mu.Unlock()
			continue // 跳过已删除的房间
		}

		// 修正 empty_since 逻辑
		var emptySince interface{} = room.EmptySince
		if userCount == 0 {
			if room.EmptySince == nil {
				emptySince = now
				_ = model.SetRoomEmptySince(database.DB, idStr, now)
			}
		} else {
			if room.EmptySince != nil {
				emptySince = nil
				_ = model.ClearRoomEmptySince(database.DB, idStr)
			}
		}

		roomInfos = append(roomInfos, map[string]interface{}{
			"id":           idStr,
			"name":         room.Name,
			"user_count":   userCount,
			"creator_id":   room.CreatorID,
			"creator_name": room.CreatorName,
			"created_at":   room.CreatedAt,
			"empty_since":  emptySince,
		})
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(roomInfos)
}

// 创建房间
func handleCreateRoom(w http.ResponseWriter, r *http.Request, wsServer *WebSocketServer) {
	var req struct {
		Name string `json:"name"`
		Tag  string `json:"tag"`
	}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil || strings.TrimSpace(req.Name) == "" {
		writeJSONError(w, "房间名不能为空", http.StatusBadRequest)
		return
	}
	userID := r.Header.Get("X-User-Id")
	userName := r.Header.Get("X-User-Name")
	if userName != "" {
		if decoded, err := url.QueryUnescape(userName); err == nil {
			userName = decoded
		}
	}
	if userID == "" || userName == "" {
		userID = r.URL.Query().Get("user_id")
		userName = r.URL.Query().Get("user_name")
	}
	if userID == "" {
		userID = "unknown"
	}
	if userName == "" {
		userName = userID
	}
	room := &model.Room{
		Name:        req.Name,
		CreatorID:   userID,
		CreatorName: userName,
		IsMatching:  false, // 默认为未匹配
		Tag:         req.Tag,
	}
	if err := model.CreateRoom(database.DB, room); err != nil {
		writeJSONError(w, "房间创建失败", http.StatusInternalServerError)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(CreateRoomResponse{
		RoomID:   fmt.Sprintf("%d", room.ID),
		RoomName: req.Name,
	})
}

// 处理 WebSocket 连接
func handleWebSocket(w http.ResponseWriter, r *http.Request, wsServer *WebSocketServer) {
	userID := r.URL.Query().Get("user_id")
	roomID := r.URL.Query().Get("room_id")
	userName := r.URL.Query().Get("user_name")
	if userID == "" || roomID == "" {
		writeJSONError(w, "missing user_id or room_id", http.StatusBadRequest)
		return
	}
	if userName == "" {
		userName = userID
	}
	// 传递userName
	q := r.URL.Query()
	q.Set("user_name", userName)
	r.URL.RawQuery = q.Encode()
	wsServer.ServeWS(w, r, userID, roomID)
}

// 登录
func handleLogin(w http.ResponseWriter, r *http.Request) {
	var req LoginRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.Username == "" {
		writeJSONError(w, "invalid request", http.StatusBadRequest)
		return
	}
	// 检查数据库连接是否初始化
	if database.DB == nil {
		writeJSONError(w, "数据库连接未初始化", http.StatusInternalServerError)
		return
	}
	// 检查用户是否已注册
	var user model.User
	result := database.DB.Where("user_name = ?", req.Username).First(&user)
	isNew := false
	if result.Error != nil || user.UserID == "" {
		// 未注册则新建
		userID := fmt.Sprintf("user-%d", time.Now().UnixNano())
		user = model.User{
			UserID:   userID,
			UserName: req.Username,
		}
		database.DB.Create(&user)
		isNew = true
	}
	token := generateToken(req.Username)
	resp := struct {
		Token   string `json:"token"`
		UserID  string `json:"user_id"`
		Message string `json:"message"`
	}{
		Token:  token,
		UserID: user.UserID,
		Message: func() string {
			if isNew {
				return "注册成功，已自动登录！"
			}
			return "登录成功！欢迎回来！"
		}(),
	}
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(resp)
}

// 获取房间在线用户列表
func handleGetRoomUsers(w http.ResponseWriter, r *http.Request, wsServer *WebSocketServer) {
	// go-zero rest 路由参数提取方式
	roomID := r.URL.Query().Get("room_id")
	if roomID == "" {
		// 兼容 /api/rooms/{room_id}/users 路径
		parts := strings.Split(r.URL.Path, "/")
		for i, part := range parts {
			if part == "rooms" && i+2 < len(parts) && parts[i+2] == "users" {
				roomID = parts[i+1]
				break
			}
		}
	}
	if roomID == "" {
		logx.Errorf("[handleGetRoomUsers] missing room_id in path: %s", r.URL.Path)
		writeJSONError(w, "房间ID不能为空", http.StatusBadRequest)
		return
	}

	// 先检查数据库中是否存在该房间
	var dbRoom model.Room
	if id, err := strconv.Atoi(roomID); err == nil {
		if err := database.DB.First(&dbRoom, id).Error; err != nil {
			logx.Errorf("[handleGetRoomUsers] room not found in database: %s, error: %v", roomID, err)
			writeJSONError(w, "房间不存在", http.StatusNotFound)
			return
		}
	}

	// 获取WebSocket房间
	room := wsServer.getRoom(roomID)
	if room == nil {
		// 如果数据库中有房间但内存中没有，说明还没有人加入
		w.Header().Set("Content-Type", "application/json")
		json.NewEncoder(w).Encode([]map[string]interface{}{})
		return
	}

	users := room.getUserList()
	logx.Infof("[handleGetRoomUsers] room %s has %d users", roomID, len(users))

	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(users); err != nil {
		logx.Errorf("[handleGetRoomUsers] failed to encode response: %v", err)
		writeJSONError(w, "服务器内部错误", http.StatusInternalServerError)
		return
	}
}

// 获取房间消息历史
func handleGetRoomMessages(w http.ResponseWriter, r *http.Request, wsServer *WebSocketServer) {
	roomID := r.URL.Query().Get("room_id")
	if roomID == "" {
		roomID = r.URL.Path[len("/api/rooms/") : len(r.URL.Path)-len("/messages")]
	}
	room := wsServer.Rooms[roomID]
	if room == nil {
		writeJSONError(w, "room not found", http.StatusNotFound)
		return
	}
	before := r.URL.Query().Get("before")
	limit := 20
	if l := r.URL.Query().Get("limit"); l != "" {
		fmt.Sscanf(l, "%d", &limit)
	}
	msgs := room.getMessages(before, limit)
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(msgs)
}

// 上报消息已读
func handleReadMessage(w http.ResponseWriter, r *http.Request, wsServer *WebSocketServer) {
	roomID := r.URL.Query().Get("room_id")
	msgID := r.URL.Query().Get("msg_id")
	if roomID == "" || msgID == "" {
		// 兼容 RESTful 路径
		path := r.URL.Path
		// /api/rooms/{room_id}/messages/{msg_id}/read
		_, err := fmt.Sscanf(path, "/api/rooms/%s/messages/%s/read", &roomID, &msgID)
		if err != nil {
			writeJSONError(w, "invalid path", http.StatusBadRequest)
			return
		}
	}
	room := wsServer.Rooms[roomID]
	if room == nil {
		writeJSONError(w, "room not found", http.StatusNotFound)
		return
	}
	var req struct {
		UserID string `json:"user_id"`
	}
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.UserID == "" {
		writeJSONError(w, "invalid request", http.StatusBadRequest)
		return
	}
	ok := room.setMessageRead(msgID, req.UserID)
	if !ok {
		writeJSONError(w, "message not found", http.StatusNotFound)
		return
	}
	w.WriteHeader(http.StatusOK)
}

// 删除房间接口
func handleDeleteRoom(w http.ResponseWriter, r *http.Request, wsServer *WebSocketServer) {
	roomID := chi.URLParam(r, "room_id")
	if roomID == "" {
		roomID = r.URL.Query().Get("room_id")
	}
	userID := r.Header.Get("X-User-Id")
	if userID == "" {
		userID = r.URL.Query().Get("user_id")
	}
	if userID == "" || roomID == "" {
		writeJSONError(w, "missing user_id or room_id", http.StatusBadRequest)
		return
	}

	// 先检查内存中的房间
	wsServer.mu.Lock()
	room := wsServer.Rooms[roomID]
	if room != nil {
		// 检查权限
		if room.CreatorID != userID {
			wsServer.mu.Unlock()
			writeJSONError(w, "no permission", http.StatusForbidden)
			return
		}

		// 关闭所有客户端连接
		room.mu.Lock()
		for _, client := range room.Clients {
			close(client.Send)
			client.Conn.Close()
		}
		room.Clients = make(map[string]*Client)
		room.mu.Unlock()

		// 从内存中删除房间
		delete(wsServer.Rooms, roomID)
	}
	wsServer.mu.Unlock()

	// 从数据库中删除房间
	if err := model.DeleteRoomByID(database.DB, roomID); err != nil {
		logx.Errorf("Failed to delete room %s from database: %v", roomID, err)
		writeJSONError(w, "delete failed", http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
}

// 获取好友列表
func handleGetFriends(w http.ResponseWriter, r *http.Request) {
	userID := r.URL.Query().Get("user_id")
	if userID == "" {
		writeJSONError(w, "missing user_id", http.StatusBadRequest)
		return
	}
	var friends []model.Friend
	database.DB.Where("user_id = ?", userID).Find(&friends)
	var friendIDs []string
	for _, f := range friends {
		friendIDs = append(friendIDs, f.FriendID)
	}
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(friendIDs)
}

// 添加好友
func handleAddFriend(w http.ResponseWriter, r *http.Request) {
	type Req struct {
		UserID   string `json:"user_id"`
		FriendID string `json:"friend_id"`
	}
	var req Req
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.UserID == "" || req.FriendID == "" {
		writeJSONError(w, "invalid request", http.StatusBadRequest)
		return
	}
	// 检查是否已存在
	var count int64
	database.DB.Model(&model.Friend{}).Where("user_id = ? AND friend_id = ?", req.UserID, req.FriendID).Count(&count)
	if count > 0 {
		writeJSONError(w, "already friends", http.StatusBadRequest)
		return
	}
	friend := model.Friend{
		UserID:   req.UserID,
		FriendID: req.FriendID,
	}
	database.DB.Create(&friend)
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("{\"message\":\"添加成功\"}"))
}

// 删除好友
func handleDeleteFriend(w http.ResponseWriter, r *http.Request) {
	userID := r.URL.Query().Get("user_id")
	friendID := r.URL.Query().Get("friend_id")
	if userID == "" || friendID == "" {
		writeJSONError(w, "missing user_id or friend_id", http.StatusBadRequest)
		return
	}
	database.DB.Where("user_id = ? AND friend_id = ?", userID, friendID).Delete(&model.Friend{})
	w.WriteHeader(http.StatusOK)
	w.Write([]byte("{\"message\":\"删除成功\"}"))
}

// 用户信息接口
func handleGetUserInfo(w http.ResponseWriter, r *http.Request) {
	userID := r.URL.Query().Get("user_id")
	if userID == "" {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusBadRequest)
		json.NewEncoder(w).Encode(map[string]string{"error": "missing user_id"})
		return
	}
	var user model.User
	result := database.DB.Where("user_id = ?", userID).First(&user)
	if result.Error != nil {
		w.Header().Set("Content-Type", "application/json")
		w.WriteHeader(http.StatusNotFound)
		json.NewEncoder(w).Encode(map[string]string{"error": "user not found"})
		return
	}
	resp := struct {
		UserID    string    `json:"user_id"`
		UserName  string    `json:"user_name"`
		CreatedAt time.Time `json:"created_at"`
	}{
		UserID:    user.UserID,
		UserName:  user.UserName,
		CreatedAt: user.CreatedAt,
	}
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(resp)
}

// 新增：查询所有匹配中房间
func handleGetMatchingRooms(w http.ResponseWriter, r *http.Request) {
	var rooms []model.Room
	err := database.DB.Where("tag = ? AND is_matching = ?", "game", true).Find(&rooms).Error
	if err != nil {
		writeJSONError(w, "查询失败", http.StatusInternalServerError)
		return
	}
	var result []map[string]interface{}
	for _, room := range rooms {
		result = append(result, map[string]interface{}{
			"room_id":      fmt.Sprintf("%d", room.ID),
			"room_name":    room.Name,
			"creator_id":   room.CreatorID,
			"creator_name": room.CreatorName,
			"tag":          room.Tag,
		})
	}
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(result)
}

// 新增：通过name+creator_id查房间数字ID的接口
func handleGetRoomIdByNameAndCreator(w http.ResponseWriter, r *http.Request) {
	name := r.URL.Query().Get("name")
	creatorID := r.URL.Query().Get("creator_id")
	if name == "" || creatorID == "" {
		writeJSONError(w, "missing name or creator_id", http.StatusBadRequest)
		return
	}
	var room model.Room
	err := database.DB.Where("name = ? AND creator_id = ?", name, creatorID).First(&room).Error
	if err != nil {
		writeJSONError(w, "room not found", http.StatusNotFound)
		return
	}
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(map[string]interface{}{
		"room_id": room.ID,
	})
}

// 设置房间为匹配中
func handleSetRoomMatching(w http.ResponseWriter, r *http.Request) {
	roomID := r.URL.Query().Get("room_id")
	if roomID == "" {
		writeJSONError(w, "missing room_id", http.StatusBadRequest)
		return
	}
	database.DB.Model(&model.Room{}).Where("id = ?", roomID).Update("is_matching", 1)
	w.WriteHeader(http.StatusOK)
}

// 取消匹配
func handleCancelRoomMatching(w http.ResponseWriter, r *http.Request) {
	roomID := r.URL.Query().Get("room_id")
	if roomID == "" {
		writeJSONError(w, "missing room_id", http.StatusBadRequest)
		return
	}
	database.DB.Model(&model.Room{}).Where("id = ?", roomID).Update("is_matching", 0)
	w.WriteHeader(http.StatusOK)
}

// 处理获取房间用户准备状态的请求
func handleGetRoomReadyStatus(w http.ResponseWriter, r *http.Request) {
	roomID := r.URL.Query().Get("room_id")
	if roomID == "" {
		writeJSONError(w, "缺少房间ID", http.StatusBadRequest)
		return
	}

	// 从数据库获取房间内所有用户的准备状态
	users, err := model.GetRoomUsersReadyStatus(database.DB, roomID)
	if err != nil {
		writeJSONError(w, fmt.Sprintf("获取用户准备状态失败: %v", err), http.StatusInternalServerError)
		return
	}

	// 转换为前端需要的格式
	type UserReadyStatus struct {
		UserID   string `json:"user_id"`
		UserName string `json:"user_name"`
		IsReady  bool   `json:"ready"`
	}

	result := make([]UserReadyStatus, 0, len(users))
	for _, user := range users {
		result = append(result, UserReadyStatus{
			UserID:   user.UserID,
			UserName: user.UserName,
			IsReady:  user.IsReady,
		})
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(result)
}

// 处理更新用户准备状态的请求
func handleUpdateUserReadyStatus(w http.ResponseWriter, r *http.Request) {
	userID := r.URL.Query().Get("user_id")
	roomID := r.URL.Query().Get("room_id")
	readyStr := r.URL.Query().Get("ready")

	if userID == "" || roomID == "" {
		writeJSONError(w, "缺少必要参数", http.StatusBadRequest)
		return
	}

	// 解析准备状态
	ready := true // 默认为准备
	if readyStr == "false" {
		ready = false
	}

	// 更新数据库中的用户准备状态
	err := model.UpdateUserReadyStatus(database.DB, userID, roomID, ready)
	if err != nil {
		writeJSONError(w, fmt.Sprintf("更新用户准备状态失败: %v", err), http.StatusInternalServerError)
		return
	}

	// 返回成功
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]interface{}{
		"success": true,
		"user_id": userID,
		"room_id": roomID,
		"ready":   ready,
	})
}

// 工具函数：统一返回JSON错误
func writeJSONError(w http.ResponseWriter, msg string, code int) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(code)
	json.NewEncoder(w).Encode(map[string]string{"error": msg})
}
